I've decided to use the live public transit feeds from NextBus to develop a Web application which outputs a prediction when the next TTC vehicle arrives at a particular stop and visualize next vehicle location on a map. Given my expertise with Web development languages (PHP, jQuery, HTML, CSS) I felt it would be appropriate to utilize and expand these skills within an academic setting. This lab will mainly focus on documenting the development process and the underlying functionalities that are not necessarily visible to the end users. It assumes the reader understands the difference between client side and server side scripting, their corresponding languages and a basic understanding of programming logic.
The app is being developed using a programming pattern known as Model-View-Controller (MVC). In short, all the programming logic is isolated away from the user interface. The view file (index.php), which contains the user interface only has two lines of php, one to load the controller; the other to initiate the controller to pull the transit route list from the model and return it to the view. The remaining user facing calls are made using a HTTP POST request with jQuery which executes PHP functions asynchronously that return results (data outputs) to the user interface without refreshing the page. In other words, it is using AJAX.
The data model (data.class.php) is the main workhorse of the application. It is an object used by the controller to parse the NextBus XML feeds into multi-dimensional arrays that are used to output information to the user interface. This is perhaps best explained by walking through the workflow of the app.
When the Web app loads (a user lands on index.php), the controller requests the data model to return a list of routes. Because the route list and configuration XML feed is updated every two weeks, the model first checks if a local copy of the XML is available. If it is available and less than two weeks old*, it uses the local copy. Otherwise it sends a request to NextBus and creates a new local copy. This significantly improves data query speeds since local data is faster than remote data. Essentailly this is a form cache. The model then parses the XML and returns a multi-dimentional array to the controller. The controller then feeds the route list array into a dropdown menu on the view (index.php). When a user picks a route, jQuery sends a HTTP POST request which tells the controller to get the route stops. Again, the controller passes this request to the model which returns an array with all the stops. The controller then outputs a populated drop down menu which jQuery catches and dynamically adds it to the view's DOM tree without reloading the page. The same process is repeated when a user selects a stop, except the arrival predictions and vehicle location data is pulled from the remote live feed. One thing to notice is that the controller behaves like a traffic cop between the data and user interface.
The next step is to pass data to Google Maps which will visualize the routes, stop locations, and vehicle locations. Due to the nature of MVC and object oriented programming, this should not be a problem as all the data parsing functions are in place.
If anyone is interested in viewing the code, you can download a rar here. I don't mind my code being re-used, but please let me know how you use it and give me credit.
Also, sorry for the lack of images. I focused on the underlying infrastucture that the visualization worklow will plug into, and felt images would not add value in this context.
*A function to check how old a file is has not been implemented as of this writing
LAB 2:
The second and current phase of development has mainly focused on integrating a visualization workflow into the existing system from Lab 1. I have decided to start with static Google Maps API and pass it values for route paths and next vehicle location to get jpeg snapshots. The static map image is created by passing parameters via a URL query. Basically, the 'src' attribute in an HTML <img> tag is the URL with the query string, i.e the Google Maps generated image.
A new model (maps.class.php) has been added into the application which is an object that returns appropriate maps based on the user input. Currently, the map model contains two functions, one to return a static map with the route path and another to return a static map with the next vehicle location. The object will be expanded to also contain functions to return javascript Google Maps (dynamic), time permitting.
The static route map function takes two parameters, the route number and the direction. The NextBus route config XML feed contains a large list of geo-coordinates which are meant to be put together to draw a path on the map. However, I ran into an issue with passing a large amount of coordinates in a URL string since the Google API limits URL strings to 2500 characters. Using all the coordinates from the route config would generate URL strings over 8000 characters. To correct the problem, I instead used coordinates for stop locations to draw the route path, reducing the URL strings to an average of 1500 characters. The route path map is working, however the only issue with it is the zoom level. I had to keep the map at a low zoom level since many routes span across long distances. Having a high zoom would cutoff the path for a significant amount of routes. The future javascript Google Maps implementation will correct this problem.
The vehicle location functions takes three parameters, the route number, direction, and the stop tag (a unique identifier). The function places a marker on the stop location and next vehicle location. The first time the function was written I was getting inaccurate markers for the closest vehicle to the stop. It turns out I overlooked that the vehicle location XML does not contain the stop tags. For some reason I confused vehicle ID with stop ID and didn't realize until I was getting gibberish results on the map. In order to place a marker for the next vehicle location I am going to have to compare the stop location coordinates to the vehicle location coordinates and figure out which are closest together. In other words, I'm going to need to write additional code I was not expecting to. Therefore, at the moment, the next vehicle location map only displays a location marker for the stop the user has selected.
I'm going to continue hacking away at this for the next week to see how far I can take it. Just as a note, I'm not particularly happy with the usability / aesthetics of the app. I'm mainly focusing on making it work, and if there is adequate time remaining, I will style it to be more appealing for the user.
Development of "Where's my TTC?":
By: Maciej Derulski
LAB 1:
I've decided to use the live public transit feeds from NextBus to develop a Web application which outputs a prediction when the next TTC vehicle arrives at a particular stop and visualize next vehicle location on a map. Given my expertise with Web development languages (PHP, jQuery, HTML, CSS) I felt it would be appropriate to utilize and expand these skills within an academic setting. This lab will mainly focus on documenting the development process and the underlying functionalities that are not necessarily visible to the end users. It assumes the reader understands the difference between client side and server side scripting, their corresponding languages and a basic understanding of programming logic.
The app is being developed using a programming pattern known as Model-View-Controller (MVC). In short, all the programming logic is isolated away from the user interface. The view file (index.php), which contains the user interface only has two lines of php, one to load the controller; the other to initiate the controller to pull the transit route list from the model and return it to the view. The remaining user facing calls are made using a HTTP POST request with jQuery which executes PHP functions asynchronously that return results (data outputs) to the user interface without refreshing the page. In other words, it is using AJAX.
The data model (data.class.php) is the main workhorse of the application. It is an object used by the controller to parse the NextBus XML feeds into multi-dimensional arrays that are used to output information to the user interface. This is perhaps best explained by walking through the workflow of the app.
When the Web app loads (a user lands on index.php), the controller requests the data model to return a list of routes. Because the route list and configuration XML feed is updated every two weeks, the model first checks if a local copy of the XML is available. If it is available and less than two weeks old*, it uses the local copy. Otherwise it sends a request to NextBus and creates a new local copy. This significantly improves data query speeds since local data is faster than remote data. Essentailly this is a form cache. The model then parses the XML and returns a multi-dimentional array to the controller. The controller then feeds the route list array into a dropdown menu on the view (index.php). When a user picks a route, jQuery sends a HTTP POST request which tells the controller to get the route stops. Again, the controller passes this request to the model which returns an array with all the stops. The controller then outputs a populated drop down menu which jQuery catches and dynamically adds it to the view's DOM tree without reloading the page. The same process is repeated when a user selects a stop, except the arrival predictions and vehicle location data is pulled from the remote live feed. One thing to notice is that the controller behaves like a traffic cop between the data and user interface.
The next step is to pass data to Google Maps which will visualize the routes, stop locations, and vehicle locations. Due to the nature of MVC and object oriented programming, this should not be a problem as all the data parsing functions are in place.
If anyone is interested in viewing the code, you can download a rar here. I don't mind my code being re-used, but please let me know how you use it and give me credit.
Also, sorry for the lack of images. I focused on the underlying infrastucture that the visualization worklow will plug into, and felt images would not add value in this context.
A demo of the app is available at http://ttc.webular.ca and a dev build is online at http://ttc.webular.ca/dev
*A function to check how old a file is has not been implemented as of this writing
LAB 2:
The second and current phase of development has mainly focused on integrating a visualization workflow into the existing system from Lab 1. I have decided to start with static Google Maps API and pass it values for route paths and next vehicle location to get jpeg snapshots. The static map image is created by passing parameters via a URL query. Basically, the 'src' attribute in an HTML <img> tag is the URL with the query string, i.e the Google Maps generated image.
A new model (maps.class.php) has been added into the application which is an object that returns appropriate maps based on the user input. Currently, the map model contains two functions, one to return a static map with the route path and another to return a static map with the next vehicle location. The object will be expanded to also contain functions to return javascript Google Maps (dynamic), time permitting.
The static route map function takes two parameters, the route number and the direction. The NextBus route config XML feed contains a large list of geo-coordinates which are meant to be put together to draw a path on the map. However, I ran into an issue with passing a large amount of coordinates in a URL string since the Google API limits URL strings to 2500 characters. Using all the coordinates from the route config would generate URL strings over 8000 characters. To correct the problem, I instead used coordinates for stop locations to draw the route path, reducing the URL strings to an average of 1500 characters. The route path map is working, however the only issue with it is the zoom level. I had to keep the map at a low zoom level since many routes span across long distances. Having a high zoom would cutoff the path for a significant amount of routes. The future javascript Google Maps implementation will correct this problem.
The vehicle location functions takes three parameters, the route number, direction, and the stop tag (a unique identifier). The function places a marker on the stop location and next vehicle location. The first time the function was written I was getting inaccurate markers for the closest vehicle to the stop. It turns out I overlooked that the vehicle location XML does not contain the stop tags. For some reason I confused vehicle ID with stop ID and didn't realize until I was getting gibberish results on the map. In order to place a marker for the next vehicle location I am going to have to compare the stop location coordinates to the vehicle location coordinates and figure out which are closest together. In other words, I'm going to need to write additional code I was not expecting to. Therefore, at the moment, the next vehicle location map only displays a location marker for the stop the user has selected.
I'm going to continue hacking away at this for the next week to see how far I can take it. Just as a note, I'm not particularly happy with the usability / aesthetics of the app. I'm mainly focusing on making it work, and if there is adequate time remaining, I will style it to be more appealing for the user.